//
//  HourGlassView.swift
//  WineComing
//
//  Created by xiaozhi on 15/7/16.
//  Copyright (c) 2015年 xiaozhi. All rights reserved.
//

import UIKit
public let middle_distance:CGFloat = 2
public let offset_distance:CGFloat = 2
public let arc_x:CGFloat = 8
public let arc_y:CGFloat = 4
class HourGlassView: UIView {
    var shapeLayer:CAShapeLayer!
    var topLayer:CAShapeLayer!
    var midLayer:CAShapeLayer!
    var bottomLayer:CAShapeLayer!
    var topLeftPoints:[CGPoint]!
    var bottomLeftPoints:[CGPoint]!
    var bottomRightPoints:[CGPoint]!
    var topRightPoints:[CGPoint]!
    var midLayerDrawPoints:[CGPoint]!
    let RenderNumber = 30
    var timer:NSTimer!
    var index:NSInteger=0
    var isCounting:Bool = false
    var countDidEndHandle:(()->Void)?
    func commInit()->Void{
        self.configureShaper()
        
        var rect = CGRectMake(0, 0, bounds.size.width, bounds.size.height/2.0)
        topLayer.frame = rect
        topLayer.fillColor = UIColor(red: 166/255.0, green: 37/255.0, blue: 57.0/255.0, alpha: 0.7).CGColor
        topLayer.strokeColor = UIColor.clearColor().CGColor
        topLayer.lineJoin = "round"
        topLayer.lineWidth = 1.0
        layer.addSublayer(topLayer)
        
        rect = bounds
        midLayer.frame = rect
        midLayer.strokeColor = UIColor(red: 166/255.0, green: 37/255.0, blue: 57.0/255.0, alpha: 0.7).CGColor
        midLayer.fillColor = UIColor.clearColor().CGColor
        midLayer.lineJoin = "round"
        midLayer.lineWidth = 1.0
        layer.addSublayer(midLayer)
        
        rect = CGRectMake(0, bounds.size.height/2.0, bounds.size.width, bounds.size.height/2.0)
        bottomLayer.frame = rect
        bottomLayer.fillColor = UIColor(red: 166/255.0, green: 37/255.0, blue: 57.0/255.0, alpha: 0.7).CGColor
        bottomLayer.strokeColor = UIColor.clearColor().CGColor
        bottomLayer.lineJoin = "round"
        bottomLayer.lineWidth = 1.0
        layer.addSublayer(bottomLayer)
    }
    func startCount(fromPersent:CGFloat,rate:NSTimeInterval){
        if isCounting{
            return
        }
        let total =  CGFloat(RenderNumber)*fromPersent
        index = NSInteger(total)
        self.configTopLayerWithNumber(RenderNumber-index-1)
        self.configBottomLayerWithNumber(index)
        timer = NSTimer.scheduledTimerWithTimeInterval(rate, target: self, selector: "startTimer:", userInfo: nil, repeats: true)
        isCounting = true
    }
    func startTimer(aTimer:NSTimer)->Void{
        self.configTopLayerWithNumber(RenderNumber-index-1)
        self.configBottomLayerWithNumber(index)
        index++
        if index>(RenderNumber-1){
            topLayer.path = nil
            midLayer.path = nil
            timer.invalidate()
            timer = nil
            index = 0
            isCounting = false
            midLayer.path = nil
            countDidEndHandle?()
        }
    }
    func stopCount()->Void{
        timer?.invalidate()
        timer = nil
        index = 0
        isCounting = false
        midLayer.removeAllAnimations()
        midLayer.removeFromSuperlayer()
    }
    func  configureShaper()->Void{
        let rect = bounds
        shapeLayer.frame = rect
        shapeLayer.fillColor = UIColor.clearColor().CGColor
        shapeLayer.strokeColor = UIColor.orangeColor().CGColor
        shapeLayer.lineJoin = "miter"
        shapeLayer.lineWidth = 1.0
        layer.addSublayer(shapeLayer)
        let shapeBound = shapeLayer.bounds
        let width = shapeBound.size.width
        let height = shapeBound.size.height
        let path = UIBezierPath()
        //预置6个点位用来绘制外观
        let topLeft = CGPointMake(0, 0)
        let topRight = CGPointMake(width, 0)
        let midLeft = CGPointMake(width/2.0-middle_distance, height/2.0)
        let midRight = CGPointMake(width/2.0+middle_distance, height/2.0)
        let bottomLeft = CGPointMake(0, height)
        let bottomRight = CGPointMake(width, height)
        //绘制，顺序为左上-->左中-->左下-->右下-->右中-->右上
        path.moveToPoint(topLeft)
        path.addQuadCurveToPoint(midLeft, controlPoint: CGPointMake(width/4-arc_x, height/4+arc_y))
        //产生左上边points
        topLeftPoints = midLeft.GenPointsArrayFrom2BezierWithPoint(topLeft, controlPoint: CGPointMake(width/4-arc_x, height/4+arc_y), divideNumber: RenderNumber)
        path.addQuadCurveToPoint(bottomLeft, controlPoint: CGPointMake(width/4-arc_x, height*3/4-arc_y))
        //产生左下边points
        bottomLeftPoints = bottomLeft.GenPointsArrayFrom2BezierWithPoint(midLeft, controlPoint: CGPointMake(width/4-arc_x, height*3/4-arc_y), divideNumber: RenderNumber)
        
        path.addLineToPoint(bottomRight)
        path.addQuadCurveToPoint(midRight, controlPoint: CGPointMake(width*3/4+arc_x, height*3/4-arc_y))
        //产生右下points
        bottomRightPoints = bottomRight.GenPointsArrayFrom2BezierWithPoint(midRight, controlPoint: CGPointMake(width*3/4+arc_x, height*3/4-arc_y), divideNumber: RenderNumber)
        path.addQuadCurveToPoint(topRight, controlPoint: CGPointMake(width*3/4+arc_x, height/4+arc_y))
        //产生右上points
        topRightPoints = midRight.GenPointsArrayFrom2BezierWithPoint(topRight, controlPoint: CGPointMake(width*3/4+arc_x, height/4+arc_y), divideNumber: RenderNumber)
        path.addLineToPoint(topLeft)
        path.closePath()
        shapeLayer.path = path.CGPath
    }
    func configTopLayerWithNumber(renderNumber:NSInteger)->Void{
        //renderNumber需要渲染的层数
        if renderNumber>=topLeftPoints.count||renderNumber<0{
            return
        }
        let shapeBound = topLayer.bounds
        let width = shapeBound.size.width
        let height = shapeBound.size.height
        let path = UIBezierPath()
        
        
        var nextPoint:CGPoint!
        
        //绘制右边
        nextPoint = CGPointMake(topRightPoints[0].x-offset_distance, topRightPoints[0].y)
        path.moveToPoint(nextPoint)
        //        path.moveToPoint(nextPoint)
        for(var i=1;i<=renderNumber;i++){
            nextPoint = CGPointMake(topRightPoints[i].x-offset_distance, topRightPoints[i].y)
            path.addLineToPoint(nextPoint)
        }
        //绘制顶边
        var controlDistance = topLeftPoints[renderNumber].y+5
        if controlDistance>height{
            controlDistance = height
        }
        path.addLineToPoint(CGPointMake(topRightPoints[renderNumber].x-offset_distance, topRightPoints[renderNumber].y))
        path.addQuadCurveToPoint(CGPointMake(topLeftPoints[renderNumber].x+offset_distance, topLeftPoints[renderNumber].y), controlPoint: CGPointMake(width/2.0, controlDistance))
        
        
        //绘制左边
        nextPoint = CGPointMake(topLeftPoints[renderNumber].x+offset_distance, topLeftPoints[renderNumber].y)
        path.addLineToPoint(nextPoint)
        for(var i=renderNumber-1;i>=0;i--){
            nextPoint = CGPointMake(topLeftPoints[i].x+offset_distance, topLeftPoints[i].y)
            path.addLineToPoint(nextPoint)
        }
        path.addLineToPoint(CGPointMake(topLeftPoints[0].x+offset_distance, topLeftPoints[0].y))
        
        //闭合下边
        nextPoint = CGPointMake(topLeftPoints[0].x+offset_distance, topLeftPoints[0].y)
        path.addLineToPoint(nextPoint)
        path.addLineToPoint(CGPointMake(topRightPoints[0].x-offset_distance, topRightPoints[0].y))
        //添加动画效果
        let pathAnimation = CABasicAnimation(keyPath: "path")
        pathAnimation.removedOnCompletion = false
        pathAnimation.duration = 0.1
        pathAnimation.fromValue = topLayer.path
        pathAnimation.toValue = path.CGPath
        pathAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionDefault)
        topLayer.addAnimation(pathAnimation, forKey: "pathAnimation")
        topLayer.path = path.CGPath
    }
    func configBottomLayerWithNumber(renderNumber:NSInteger)->Void{
        //renderNumber需要渲染的层数
        if renderNumber>=topLeftPoints.count||renderNumber<0{
            return
        }
        let shapeBound = bottomLayer.bounds
        let width = shapeBound.size.width
        let height = shapeBound.size.height
        let path = UIBezierPath()
        
        
        var nextPoint:CGPoint!
        
        //绘制右边
        nextPoint = CGPointMake(bottomRightPoints[0].x-offset_distance, bottomRightPoints[0].y-height)
        path.moveToPoint(nextPoint)
        //        path.moveToPoint(nextPoint)
        for(var i=1;i<=renderNumber;i++){
            nextPoint = CGPointMake(bottomRightPoints[i].x-offset_distance, bottomRightPoints[i].y-height)
            path.addLineToPoint(nextPoint)
        }
        //绘制顶边
        var controlDistance = bottomLeftPoints[renderNumber].y-3-height
        if controlDistance<0{
            controlDistance = 0
        }
        
        path.addLineToPoint(CGPointMake(bottomRightPoints[renderNumber].x-offset_distance, bottomRightPoints[renderNumber].y-height))
        path.addQuadCurveToPoint(CGPointMake(bottomLeftPoints[renderNumber].x+offset_distance, bottomLeftPoints[renderNumber].y-height), controlPoint: CGPointMake(width/2.0, controlDistance))
        
        
        //绘制左边
        nextPoint = CGPointMake(bottomLeftPoints[renderNumber].x+offset_distance, bottomLeftPoints[renderNumber].y-height)
        path.addLineToPoint(nextPoint)
        for(var i=renderNumber-1;i>=0;i--){
            nextPoint = CGPointMake(bottomLeftPoints[i].x+offset_distance, bottomLeftPoints[i].y-height)
            path.addLineToPoint(nextPoint)
        }
        path.addLineToPoint(CGPointMake(bottomLeftPoints[0].x+offset_distance, bottomLeftPoints[0].y-height))
        
        //闭合下边
        nextPoint = CGPointMake(bottomLeftPoints[0].x+offset_distance, bottomLeftPoints[0].y-height)
        path.addLineToPoint(nextPoint)
        path.addLineToPoint(CGPointMake(bottomRightPoints[0].x-offset_distance, bottomRightPoints[0].y-height))
        //添加动画效果
        let pathAnimation = CABasicAnimation(keyPath: "path")
        pathAnimation.removedOnCompletion = false
        pathAnimation.duration = 0.1
        pathAnimation.fromValue = bottomLayer.path
        pathAnimation.toValue = path.CGPath
        pathAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionDefault)
        bottomLayer.addAnimation(pathAnimation, forKey: "bottomLayerAnimation")
        bottomLayer.path = path.CGPath
        
        let  centerPoint = CGPointMake(width/2.0, height-1)
        let  endPoint = CGPointMake(width/2.0, bottomLeftPoints[renderNumber].y)
        midLayerDrawPoints = centerPoint.GenPointsArrayFromBezierWithPoint(endPoint, dividNumber: 12)
        self.configMidLayer()
    }
    func configMidLayer()->Void{
        let shapeBound = midLayer.bounds
        let width = shapeBound.size.width
        let height = shapeBound.size.height
        let path = UIBezierPath()
        for(var i = 0;i<=10;i+=2){
            path.moveToPoint(midLayerDrawPoints[i])
            path.addLineToPoint(midLayerDrawPoints[i+1])
        }
        let path1 = UIBezierPath()
        for(var i = 2;i<=10;i+=2){
            path1.moveToPoint(midLayerDrawPoints[i])
            path1.addLineToPoint(midLayerDrawPoints[i+1])
        }
        let pathAnimation = CABasicAnimation(keyPath: "path")
        pathAnimation.removedOnCompletion = false
        pathAnimation.duration = 0.2
        pathAnimation.repeatCount = 60000
        pathAnimation.fromValue = path.CGPath
        pathAnimation.toValue = path1.CGPath
        pathAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionDefault)
        midLayer.addAnimation(pathAnimation, forKey: "midLayerAnimation")
        midLayer.path = path.CGPath
    }
    override init(frame: CGRect) {
        shapeLayer = CAShapeLayer()
        topLayer = CAShapeLayer()
        midLayer = CAShapeLayer()
        bottomLayer = CAShapeLayer()
        super.init(frame: frame)
        self.commInit()
    }
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
     deinit{
        print("deinit hourGlass")
    }
}
extension CGPoint{
    func GenBezierPointWithPoint(point:CGPoint,size s:CGFloat)->CGPoint?{
        if s<0.0||s>1.0{
            return nil
        }
        var aPoint = CGPointZero
        aPoint.x = self.x*(1-s)+point.x*s
        aPoint.y = self.y*(1-s)+point.y*s
        return aPoint
    }
    func Gen2BezierPointWithPoint(endPoint:CGPoint,controlPoint:CGPoint,size s:CGFloat)->CGPoint?{
        if s<0.0||s>1.0{
            return nil
        }
        if let p3 = self.GenBezierPointWithPoint(controlPoint, size: s){
            if let p4 = controlPoint.GenBezierPointWithPoint(endPoint, size: s){
                if let aPoint = p3.GenBezierPointWithPoint(p4, size: s){
                    return aPoint
                }
            }
        }
        return nil
    }
    func GenPointsArrayFrom2BezierWithPoint(endPoint:CGPoint,controlPoint:CGPoint,divideNumber number:Int)->[CGPoint]{
        var array = [CGPoint]()
        let size:CGFloat = 1/CGFloat(number)
        for i in 1...number{
            let currentSize = CGFloat(i)*size
            if let point = self.Gen2BezierPointWithPoint(endPoint, controlPoint: controlPoint, size:currentSize){
                array.append(point)
            }
        }
        return array
    }
    func GenPointsArrayFromBezierWithPoint(endPoint:CGPoint,dividNumber:Int)->[CGPoint]{
        var array = [CGPoint]()
        let size:CGFloat = 1/CGFloat(dividNumber)
        for i in 1...dividNumber{
            let currentSize = CGFloat(i)*size
            if let point = self.GenBezierPointWithPoint(endPoint, size:currentSize){
                array.append(point)
            }
        }
        return array
    }
}
